﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic;
using WD.Db.Contract;
using WD.Db.Contract.Model;
using WD.Db.DAL;
using WD.Framework.Utility;
using System.Data.Objects;
using WD.Framework.Contract;
using EntityFramework.Extensions;
using WD.Core.Cache;
using WD.Core.Config;

namespace WD.Db.BLL
{
    /// <summary>
    /// 登录信息处理类
    /// </summary>
    public class AccountHandle
    {
        public AccountHandle(int accountType)
        {
            AccountType = accountType;
        }

        //前后台用户类型区分 使用前先赋值 或者  AccountHandle _handle = new AccountHandle((int)账户凭证类型.管理员);
        public int AccountType = (int)账户凭证类型.其它;

        private readonly int _userLoginTimeoutMinutes = CachedConfigContext.Current.SystemConfig.UserLoginTimeoutMinutes;
        private const string LoginInfoKeyFormat = "LoginInfo_{0}";

        public Rbac_LoginInfo Login(string loginName, string password)
        {
            Rbac_LoginInfo loginInfo = null;

            password = Encrypt.MD5(password);
            loginName = loginName.Trim();

            switch (AccountType)
            {
                case (int)账户凭证类型.商家:
                    loginInfo = _LoginShop(loginName, password);
                    break;
                case (int)账户凭证类型.管理员:
                    loginInfo = _LoginManager(loginName, password);
                    break;
            }

            return loginInfo;
        }

        #region 登录实现

        /// <summary>
        /// 后台管理员登录
        /// </summary>
        /// <param name="loginId"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        private Rbac_LoginInfo _LoginManager(string loginId, string password)
        {
            Rbac_LoginInfo loginInfo = null;
            using (var dbContext = new AccountDbContext())
            {
                var user = dbContext.Rbac_User.FirstOrDefault(u => u.UserID == loginId && u.PWD == password && u.IsDeleted == false);
                if (user != null)
                {
                    var ip = Fetch.UserIp;
                    loginInfo = dbContext.Rbac_LoginInfo.FirstOrDefault(p => p.LoginId == loginId && p.ClientIP == ip && p.EnumLoginAccountType == AccountType);
                    if (loginInfo != null)
                    {
                        loginInfo.LastAccessTime = DateTime.Now;
                    }
                    else
                    {
                        loginInfo = new Rbac_LoginInfo(user.ID, user.UserName, user.UserID);
                        loginInfo.ClientIP = ip;
                        loginInfo.EnumLoginAccountType = AccountType;
                        //TODO 查询权限列表
                        var funIdList = new List<string>();
                        var roleList = user.Rbac_Role;
                        if (roleList.Any(x => x.ID == CommonCode.超级管理员角色ID))
                        {
                            roleList = dbContext.Rbac_Role.ToList();
                        }

                        foreach (var role in roleList)
                        {
                            funIdList.AddRange(role.Rbac_FunctionModel.Where(x => x.Url != null).Select(x => x.Url).ToList());
                        }

                        loginInfo.BusinessPermissionList = funIdList;

                        dbContext.Insert(loginInfo);
                    }
                }
            }
            return loginInfo;
        }

        /// <summary>
        /// 商家登录
        /// </summary>
        /// <param name="loginId"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        private Rbac_LoginInfo _LoginShop(string loginId, string password)
        {
            Rbac_LoginInfo loginInfo = null;
            using (var dbContext = new AccountDbContext())
            {
                var user = dbContext.User.FirstOrDefault(u => u.UserId == loginId && u.Pwd == password && u.IsDeleted == false);
                if (user != null)
                {
                    //TODO 添加商家权限
                    var funIdList = new List<int>()
                            {
                                //PageFunctionId.兑现卡管理,
                                //PageFunctionId.兑现卡管理_兑现卡列表,
                                //PageFunctionId.兑现卡管理_兑现卡列表_查看对显卡,
                                //PageFunctionId.兑现卡管理_兑现卡列表_购买对显卡,
                                //PageFunctionId.兑现卡管理_兑现卡列表_赠送兑现卡,
                                //PageFunctionId.兑现卡管理_兑现卡列表_确认赠送兑现卡,
                                //PageFunctionId.兑现卡管理_兑现卡列表_兑现卡排队
                            };
                    //TODO 查询权限列表
                    var funUrlList = dbContext.Rbac_FunctionModel.Where(x => funIdList.Contains(x.ID) && x.Url != null)
                                 .Select(x => x.Url)
                                 .ToList();

                    var ip = Fetch.UserIp;
                    //TODO 查询用户是否存在登录信息
                    loginInfo = dbContext.Rbac_LoginInfo.FirstOrDefault(p => p.LoginId == loginId
                        && p.ClientIP == ip && p.EnumLoginAccountType == AccountType);
                    loginInfo = loginInfo ?? new Rbac_LoginInfo(user.ID, user.Name, user.UserId);
                    //TODO 写入登录信息
                    loginInfo.LastAccessTime = DateTime.Now;
                    loginInfo.BusinessPermissionIdList = funIdList;
                    loginInfo.BusinessPermissionList = funUrlList;
                    loginInfo.ClientIP = ip;
                    loginInfo.EnumLoginAccountType = AccountType;
                    //loginInfo.ShopId = user.ShopId;     //商家店铺编号
                    loginInfo = loginInfo.ID > 0
                        ? dbContext.Update(loginInfo)
                        : dbContext.Insert(loginInfo);

                }
            }
            return loginInfo;
        }

        #endregion

        /// <summary>
        /// 删除登录信息
        /// </summary>
        /// <param name="token"></param>
        public void Logout(Guid token)
        {
            using (var dbContext = new AccountDbContext())
            {
                var loginInfo = dbContext.FindAll<Rbac_LoginInfo>(l => l.LoginToken == token && l.EnumLoginAccountType == AccountType).FirstOrDefault();
                if (loginInfo != null)
                {
                    dbContext.Delete(loginInfo);
                }
            }

            CacheHelper.Remove(string.Format(LoginInfoKeyFormat, token));
        }

        /// <summary>
        /// 根据TOKEN获取登录信息
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public Rbac_LoginInfo GetLoginInfo(Guid token)
        {
            return CacheHelper.Get(string.Format(LoginInfoKeyFormat, token), () =>
            {
                using (var dbContext = new AccountDbContext())
                {
                    //如果有超时的，启动超时处理
                    var timeoutList = dbContext.FindAll<Rbac_LoginInfo>(p => EntityFunctions.DiffMinutes(DateTime.Now, p.LastAccessTime) > _userLoginTimeoutMinutes);
                    if (timeoutList.Count > 0)
                    {
                        foreach (var li in timeoutList)
                            dbContext.Rbac_LoginInfo.Remove(li);
                    }

                    dbContext.SaveChanges();


                    var loginInfo = dbContext.FindAll<Rbac_LoginInfo>(l => l.LoginToken == token && l.EnumLoginAccountType == AccountType).FirstOrDefault();
                    if (loginInfo != null)
                    {
                        loginInfo.LastAccessTime = DateTime.Now;
                        dbContext.Update(loginInfo);
                    }

                    return loginInfo;
                }
            });
        }

        public Guid SaveVerifyCode(string verifyCodeText)
        {
            if (string.IsNullOrWhiteSpace(verifyCodeText))
                throw new BusinessException("verifyCode", "输入的验证码不能为空！");

            using (var dbContext = new AccountDbContext())
            {
                var verifyCode = new Rbac_VerifyCode() { VerifyText = verifyCodeText, Guid = Guid.NewGuid() };
                dbContext.Insert(verifyCode);
                return verifyCode.Guid;
            }
        }

        public bool CheckVerifyCode(string verifyCodeText, Guid guid)
        {
            using (var dbContext = new AccountDbContext())
            {
                var verifyCode = dbContext.FindAll<Rbac_VerifyCode>(v => v.Guid == guid && v.VerifyText == verifyCodeText).LastOrDefault();
                if (verifyCode != null)
                {
                    dbContext.Rbac_VerifyCode.Remove(verifyCode);
                    dbContext.SaveChanges();

                    //清除验证码大于2分钟还没请求的
                    var expiredTime = DateTime.Now.AddMinutes(-2);
                    dbContext.Rbac_VerifyCode.Where(v => v.CreateTime < expiredTime).Delete();

                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
    }
}
